/**
 * WebUploader 封装类（fileupload.tag）
 * @author ThinkGem@163.COM
 * @version 2015-7-7
 */
(function($){
	
	var Webuploader = function(options, $this){

		var opts = $.extend({}, $.fn.webuploader.defaults, options),
		id = opts.id, md5 = "", imageFlag = opts.uploadType == 'image', //是否仅图片控件
		$wrap = $('#'+id+'Uploader'), $queue = $wrap.find('#'+id+'fileLists'); // 容器
		
		// 如果是图片控件
		if(imageFlag){
			$queue.appendTo($wrap.find('.queueList'));
		}
		
     	// 状态栏，包括进度和控制按钮
	    var $statusBar = $wrap.find('.statusBar'),
        
        // 文件总体选择信息。
        $info = $statusBar.find('.info'),
      
        // 上传按钮
        $upload = $wrap.find('.uploadBtn'),
        
        // 没选择文件之前的内容。
        $placeHolder = $wrap.find('.placeholder'),
        
        // 总体进度条
        $progress = $statusBar.find('.progress').hide(),
        
        // 添加的文件数量
        fileCount = 0,
        
        // 添加的文件总大小
        fileSize = 0,
        
        // 优化retina, 在retina下这个值是2
        ratio = window.devicePixelRatio || 1,
        
        // 缩略图大小
        thumbnailWidth = 110 * ratio,
        thumbnailHeight = 110 * ratio,
        
        // 可能有pedding, ready, uploading, confirm, done.
        state = 'pedding',
        // 所有文件的进度信息，key为file id
        percentages = {},
        
        /*-------------------普通文件独有 start------------------------*/
        // 判断浏览器是否支持图片的base64
        isSupportBase64 = (function() {
            var data = new Image();
            var support = true;
            data.onload = data.onerror = function() {
                if (this.width != 1 || this.height != 1) {
                    support = false;
                }
            }
            data.src = "";
            return support;
        })(),
        // 检测是否已经安装flash，检测flash的版本
        flashVersion = (function() {
            var version;
            try {
                version = navigator.plugins['Shockwave Flash'];
                version = version.description;
            } catch(ex) {
                try {
                    version = new ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$version');
                } catch(ex2) {
                    version = '0.0';
                }
            }
            version = version.match(/\d+/g);
            return parseFloat(version[0] + '.' + version[1], 10);
        })(),
        /*-------------------普通文件独有 end------------------------*/
	      
        supportTransition = (function() {
            var s = document.createElement('p').style,
            r = 'transition' in s
	           || 'WebkitTransition' in s
	           || 'MozTransition' in s
	           || 'msTransition' in s || 'OTransition' in s;
            s = null;
            return r;
        })(),
        
        // 文件用户ID串
        fileUsers = [],
        
        // 文件路径字符串
        filePaths = [],
        
        // 文件名称字符串
        fileNames = [],
	    
        // 上传表单参数
        formData = {
	        "bizCategory" : opts.bizCategory,
	        "bizKey" : opts.bizKey,
	        "uploadType" : opts.uploadType,
	        "imageMaxWidth" : opts.imageMaxWidth,
	        "imageMaxHeight" : opts.imageMaxHeight,
	        "allowServerSelect" : opts.allowServerSelect,
	        "maxUploadNum" : opts.maxUploadNum,
	        "lazyUpload" : opts.lazyUpload
        };
        
        if (!WebUploader.Uploader.support('flash')&& WebUploader.browser.ie) {
            // flash 安装了但是版本过低。
            if (flashVersion) {
                (function(container) {
                    window['expressinstallcallback'] = function(state) {
                        switch (state) {
                            case 'Download.Cancelled':
	                           alert('您取消了更新！')
	                           break;
                            case 'Download.Failed':
	                           alert('安装失败！')
	                           break;
                            default:
	                           alert('安装已成功，请刷新！');
	                           break;
                        }
                        delete window['expressinstallcallback'];
                    };
                    var swf = opts.ctxStatic+'/webuploader/attachment/expressInstall.swf';
                    // insert flash object
                    var html = '<object type="application/' + 'x-shockwave-flash" data="' + swf + '" ';
                    if (WebUploader.browser.ie) {
                        html += 'classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" ';
                    }
                    html += 'width="100%" height="100%" style="outline:0">'
	                   + '<param name="movie" value="' + swf + '" />'
	                   + '<param name="wmode" value="transparent" />'
	                   + '<param name="allowscriptaccess" value="always" />'
	                   + '</object>';
                    container.html(html);
                })($wrap);
            } else {
                $wrap.html('<a href="http://www.adobe.com/go/getflashplayer" target="_blank" border="0"><img alt="get flash player" src="http://www.adobe.com/macromedia/style_guide/images/160x41_Get_Flash_Player.jpg" /></a>');
            }
            return;
        } else if (!WebUploader.Uploader.support()) {
            alert('Web Uploader 不支持您的浏览器！');
            return;
        }
        
        // 实例化上传组件
        var options = {};
      	if(!eval(opts.readonly)){
        	// 图片上传
      		if(imageFlag){
	        	options = $.extend({},{
	        		pick: {
	    	            id: '#'+id+'filePicker',
	    	            label: '点击选择图片'
	    	        },
	    	        dnd: '#'+id+'Uploader .queueList',
	    	        paste: '#'+id+'Uploader .queueList',
	    	        accept: {
	    	            title: 'Images',
	    	            extensions: 'gif,bmp,jpeg,jpg,ico,png,tif,tiff',
	    	            mimeTypes: 'image/*'
	    	        }
	        	});
        	}
      		// 文件上传
      		else{
 	        	options = $.extend({},{
	        		pick: {
	    	            id: '#'+id+'filePicker',
	    	            label: '点击选择文件'
	    	        },
 	    	        dnd: '#'+id+'Uploader .queueList',
 	    	        paste: '#'+id+'Uploader .queueList'
 	        	});
        	}
        }
        options = $.extend({},{
        	disableGlobalDnd: true , // 禁掉全局的拖拽功能。这样不会出现图片拖进页面的时候，把图片打开。
        	swf: opts.ctxStatic+'/webuploader/0.1.5/Uploader.swf',
        	server: opts.ctx+'/file/upload',
        	formData: formData,
            threads: 1, // 最大上传线程数
	        fileNumLimit: opts.maxUploadNum,		// 文件个数
	        fileSingleSizeLimit: opts.maxFileSize,    // 单文件
	        fileSizeLimit: opts.maxFilesSize    // 总大小
        }, options);
        
	    var uploader = WebUploader.create(options);
	       
        /*-------------------普通文件独有 start------------------------*/
        // 拖拽时不接受 js, txt文件。
        uploader.on('dndAccept', function(items) {
            var denied = false, len = items.length, i = 0,
            // 修改js类型
            unAllowed = 'text/plain;application/javascript ';
            for (; i < len; i++) {
                // 如果在列表里面
                if (~unAllowed.indexOf(items[i].type)) {
                    denied = true;
                    break;
                }
            }
            return ! denied;
        });
        /*-------------------普通文件独有 end------------------------*/
	      
        // 添加“添加文件”的按钮，
        uploader.addButton({
            id: '#'+id+'filePicker2',
            label: '继续添加'
        });
        
        // 如果不是懒加载
        if (!opts.lazyUpload){
	    	$upload.hide();
	    }
        
        // 当有文件添加进来时执行，负责view的创建
        function addFile(file) {
        	loading('正在验证文件，请稍等。');
        	$upload.addClass('disabled');
            uploader.md5File(file).then(function(val) {

            	// 添加文件
                fileCount++;
                fileSize += file.size;
                if (fileCount === 1) {
                	if(!eval(opts.readonly)){
                		$statusBar.show();
                	}
                }
                
            	// 图片列表格式
            	if(imageFlag){
            		var $li = $('<li id="'+ id + file.id + '">'
            			+ '<input id="'+id + file.id + '_md5" name="'+id + file.id + '_md5" type="hidden" value="' + val + '"/>'
            			+ '<p class="title">' + file.name + '</p>'
            			+ '<p class="imgWrap"></p>'
            			+ '<p class="progress"><span></span></p>'
            			+ '</li>' ),
        			$btns = $('<div class="file-panel">'
        				+ '<span class="cancel">删除</span>'
        				//+ '<span class="rotateRight">向右旋转</span>'
        				//+ '<span class="rotateLeft">向左旋转</span>'
        				+ '</div>').appendTo($li),
        			$prgress = $li.find('p.progress span'),
        			$wrap = $li.find( 'p.imgWrap' ),
        			$info = $('<p class="error"></p>'),

        			showError = function( code ) {
	        			switch (code) {
//		                    case 'exceed_size':
//		                       text = "文件大小超出";
//		                       break;
		                    case 'interrupt':
		                       text = "文件传输中断";
		                       break;
		                    case 'http':
		                       text = "HTTP请求错误";
		                       break;
//		                    case 'not_allow_type':
//		                       text = "文件格式不允许";
//		                       break;
		                    case 'server':
		                       text = "文件不存在";
		                       break;
//		                    default:
//		                       text = "上传失败，请重试";
//		                       break;
		                }
	        			if (text != null){
	        				$info.text(text).appendTo($li);
	        			}
        			};

            		if ( file.getStatus() === 'invalid' ) {
            			showError( file.statusText );
            		} else {
            			$wrap.text( '预览中' );
            			uploader.makeThumb( file, function( error, src ) {
            				if ( error ) {
            					$wrap.text( '不能预览' );
            					return;
            				}

            				var img = $('<img src="'+src+'">');
            				$wrap.empty().append( img );
            			}, thumbnailWidth, thumbnailHeight );

            			percentages[ file.id ] = [ file.size, 0 ];
            			file.rotation = 0;
            		}

            		file.on('statuschange', function( cur, prev ) {
            			if ( prev === 'progress' ) {
            				$prgress.hide().width(0);
            			} else if ( prev === 'queued' ) {
//            				$li.off( 'mouseenter mouseleave' );
//            				$btns.remove();
            			}

            			// 成功
            			if ( cur === 'error' || cur === 'invalid' ) {
            				showError( file.statusText );
            				percentages[ file.id ][ 1 ] = 1;
            			} else if ( cur === 'interrupt' ) {
            				showError( 'interrupt' );
            			} else if ( cur === 'queued' ) {
            				percentages[ file.id ][ 1 ] = 0;
            			} else if ( cur === 'progress' ) {
            				$info.remove();
            				$prgress.css('display', 'block');
            			} else if ( cur === 'complete' ) {
            				$li.append( '<span class="success"></span>' );
            			}

            			$li.removeClass( 'state-' + prev ).addClass( 'state-' + cur );
            		});

            		$li.on( 'mouseenter', function() {
            			$btns.stop().animate({height: 30});
            		});

            		$li.on( 'mouseleave', function() {
            			$btns.stop().animate({height: 0});
            		});

            		$btns.on( 'click', 'span', function() {
            			var index = $(this).index(), deg;
            			switch ( index ) {
            				case 0:
            					var fuid = $(this).attr("fileUserId"),
            						fileDownloadPath = $(this).attr("fileDownloadPath"),
            						fileName = $(this).attr("fileName"),
            						formData = {"fileUserId" : fuid, "fileId" : $(this).attr("fileId")};
            					if (fuid && fuid != null){
     		                        confirmx("确定删除该图片吗？  确定后即生效！", opts.ctx+"/file/delFile", formData,  function(data) {
     		                           if (data) {
     		                               if (data.result == "true") {
     		                            	  if (opts.returnPath){
         		                            	  filePaths.splice($.inArray(fileDownloadPath, filePaths), 1);
         		                            	  fileNames.splice($.inArray(fileName, fileNames), 1);
         		                            	  $('#'+id).val(filePaths.join('|'));
         		                            	  $('#'+opts.filePathInputId).val($('#'+id).val());
         		                            	  $('#'+opts.fileNameInputId).val(fileNames.join('|'));
     		                            	  }else{
         		                            	  fileUsers.splice($.inArray(fuid, fileUsers), 1);
         		                            	  $('#'+id).val(fileUsers.join(','));
     		                            	  }
     		                                  uploader.removeFile(file);
     		                               }
     		                               showMessage(data.message);
     		                           }
     		                       });
            					}else{
                					uploader.removeFile( file );
            					}
            					return;
            				case 1:
            					file.rotation += 90;
            					break;
            				case 2:
            					file.rotation -= 90;
            					break;
            			}
            			if ( supportTransition ) {
            				deg = 'rotate(' + file.rotation + 'deg)';
            				$wrap.css({
            					'-webkit-transform': deg,
            					'-mos-transform': deg,
            					'-o-transform': deg,
            					'transform': deg
            				});
            			} else {
            				$wrap.css( 'filter', 'progid:DXImageTransform.Microsoft.BasicImage(rotation='+ (~~((file.rotation/90)%4 + 4)%4) +')');
            			}

            		});

            	// 文件列表格式
            	}else{
            		
            		var $li = $('<tr id="'+id + file.id + '" class="template-upload"><input id="'+id + file.id + '_md5" name="'+id + file.id + '_md5" type="hidden" value="' + val + '"/>'
    		               + '<td class="name">'+ file.name+ '</td>'
    		               + '<td class="size">'+ WebUploader.formatSize(file.size)+ '</td>'
    		               + '<td class="prog_bar"><p class="progress" style="margin-bottom:0px;padding:1px 3px;"><span class="text">0%</span><span class="percentage"></span></p></td>'
    		               + '</tr>'),
	                $prgress = $li.find('p.progress span'),
	                $info = $('<td class="msg"></td>'),
	                showError = function(code) {
	                    var text = "";
	                    switch (code) {
//	                        case 'exceed_size':
//		                       text = "<span class='label label-sm label-danger'>文件大小超出</span>";
//		                       break;
	                        case 'interrupt':
		                       text = "<span class='label label-sm label-danger'>文件传输中断</span>";
		                       break;
	                        case 'http':
		                       text = "<span class='label label-sm label-danger'>HTTP请求错误</span>";
		                       break;
//	                        case 'not_allow_type':
//		                       text = "<span class='label label-sm label-danger'>文件格式不允许</span>";
//		                       break;
	                        case 'server':
		                       text = "<span class='label label-sm label-danger'>文件不存在</span>";
		                       break;
//	                        default:
//		                       text = "<span class='label label-sm label-danger'>上传失败，请重试</span>";
//		                       break;
	                    }
	                    if(text != null){
		                    $info.html(text);
	                    }
	                };
	                
	                if (file.getStatus() === 'invalid') {
	                    showError(file.statusText);
	                    $info.appendTo($li);
	                } else {
	                    percentages[file.id] = [file.size, 0];
	                    file.rotation = 0;
	                    $info.text("等待上传").appendTo($li);
	                }
	                
	                file.on('statuschange', function(cur, prev) {
	                    if (prev === 'progress') {
	                        //$prgress.hide().width(0);
	                    } else if (prev === 'queued') {
	                        //$btns.remove();
	                    }
	                    // 成功
	                    if (cur === 'error'|| cur === 'invalid') {
	                        showError(file.statusText);
	                        percentages[file.id][1] = 1;
	                        $prgress.eq(0).text('0%');
	                        $prgress.eq(1).css('width', '0%');
	                    } else if (cur === 'interrupt') {
	                        showError('interrupt');
	                        $prgress.eq(0).text('0%');
	                        $prgress.eq(1).css('width', '0%');
	                    } else if (cur === 'queued') {
	                        percentages[file.id][1] = 0;
	                        $prgress.eq(0).text('0%');
	                        $prgress.eq(1).css('width', '0%');
	                    } else if (cur === 'progress') {
	                        //$info.remove();
	                        $info.text("正在上传");
	                        $prgress.css('display',  'block');
	                    } else if (cur === 'complete') {
	                    	// $prgress.css('display',  'none');
	                    }
	                    $li.removeClass('state-'+ prev).addClass('state-'+ cur);
	                });
	                
	                $btns = $('<td class="btncancel"><a class="btn default btn-xs yellow"><i class="fa fa-ban"></i> 取消 </a></td>').appendTo($li);
	                $btns.on('click', 'a', function() {
	                    var index = $(this).index();
	                    switch (index) {
	                        case 0:
		                       uploader.removeFile(file);
		                       return;
	                        case 1:
		                       var fuid = $(this).attr("fileUserId"),
		                           fileDownloadPath = $(this).attr("fileDownloadPath"),
		                           fileName = $(this).attr("fileName"),
		                           formData = {"fileUserId" : fuid, "fileId" : $(this).attr("fileId")};
		                       confirmx("确定删除该文件吗？  确定后即生效！", opts.ctx+"/file/delFile", formData,  function(data) {
		                           if (data) {
		                               if (data.result == "true") {
  		                            	  if (opts.returnPath){
     		                            	  filePaths.splice($.inArray(fileDownloadPath, filePaths), 1);
     		                            	  fileNames.splice($.inArray(fileName, fileNames), 1);
     		                            	  $('#'+id).val(filePaths.join('|'));
     		                            	  $('#'+opts.filePathInputId).val($('#'+id).val());
     		                            	  $('#'+opts.fileNameInputId).val(fileNames.join('|'));
 		                            	  }else{
      		                            	  fileUsers.splice($.inArray(fuid, fileUsers), 1);
     		                            	  $('#'+id).val(fileUsers.join(','));
 		                            	  }
		                                  uploader.removeFile(file);
		                               }
		                               showMessage(data.message);
		                           }
		                       });
		                       return;
	                    };
	                });
            	}
            	$li.appendTo($queue);	
                setState('ready');
                updateTotalProgress();
            	$upload.removeClass('disabled');
            	if (!opts.lazyUpload){
            		$upload.click();
            	}
            	closeLoading();
            });
        }
        
        function updateTotalProgress() {
            var loaded = 0, 
            total = 0,
            spans = $progress.children(), 
            percent;
            $.each(percentages,  function(k, v) {
                total += v[0];
                loaded += v[0] * v[1];
            });
            percent = total ? loaded / total: 0;
            spans.eq(0).text(Math.round(percent * 100) + '%');
            spans.eq(1).css('width', Math.round(percent * 100) + '%');
            updateStatus();
        }
        
        function updateStatus() {
            var text = '', stats;
            if (state === 'ready') {
            	 if(imageFlag){
            	     text = '共' + fileCount + '张图片' + (fileSize <= 0 ? '' : '（' + WebUploader.formatSize(fileSize) + '）');
            	 }else{
            		 text = '共' + fileCount + '个文件' + (fileSize <= 0 ? '' : '（'+ WebUploader.formatSize(fileSize) + '）');
            	 }
            } else if (state === 'confirm') {
                stats = uploader.getStats();
                if (stats.uploadFailNum) {
                	if(imageFlag){
                		text = stats.uploadFailNum + '张图片上传失败，<a class="retry" href="#">重新上传</a>失败或<a class="ignore" href="#">忽略</a>';
                	}else{
	                	text = stats.uploadFailNum + '个文件上传失败，<a class="retry" href="#">重新上传</a>失败或<a class="ignore" href="#">忽略</a>';
                	}
            	 }
            } else {
                stats = uploader.getStats();
                if(imageFlag){
                	text = '已成功上传' + fileCount + '张图片' + (fileSize <= 0 ? '' : '（'+ WebUploader.formatSize(fileSize) + '）');
                }else{
                	text = '已成功上传' + fileCount + '个文件' + (fileSize <= 0 ? '' : '（'+ WebUploader.formatSize(fileSize) + '）');
                }
                if (stats.uploadFailNum) {
                    text += '，失败' + stats.uploadFailNum + '个';
                }
            }
            $info.html(text);
            // 超过限制，不显示继续添加按钮
            if (fileCount < opts.maxUploadNum){
            	$('#'+id+'filePicker2').show();
            }else{
            	$('#'+id+'filePicker2').hide();
            }
        }

        function setState(val) {
            var file,stats;
            if (val === state) {
                return;
            }
            $upload.removeClass('state-' + state);
            $upload.addClass('state-' + val);
            state = val;
            switch (state) {
                case 'pedding':
	               $placeHolder.removeClass('element-invisible');
	               if(imageFlag){
	               	  $queue.parent().removeClass('filled');
	               }
	               $queue.hide();
	               $statusBar.addClass('element-invisible');
	               uploader.refresh();
	               break;
                case 'ready':
	               $placeHolder.addClass('element-invisible');
	               $('#'+id+'filePicker2').removeClass('element-invisible');
	               if(imageFlag){
	               	  $queue.parent().removeClass('filled');
	               }
	               $queue.show();
	               $statusBar.removeClass('element-invisible');
	               uploader.refresh();
	               break;
                case 'uploading':
	               $('#'+id+'filePicker2').addClass('element-invisible');
	               $progress.show();
	               $upload.text('暂停上传');
	               break;
                case 'paused':
	               $progress.show();
	               $upload.text('继续上传');
	               break;
                case 'confirm':
	               $progress.hide();
	               if(imageFlag){
	                  //是否继续添加图片
	               	  $('#'+id+'filePicker2').removeClass('element-invisible');
	               	  $upload.text('开始上传')
	               }else{
	               	  $('#'+id+'filePicker2').removeClass('element-invisible');
	               	  $upload.text('开始上传');
	               }
	               stats = uploader.getStats();
	               if (stats.successNum && !stats.uploadFailNum) {
	                  setState('finish');
	                  return;
	               }
	               break;
                case 'finish':
	               stats = uploader.getStats();
	               if (stats.successNum) {
	                  //alert('上传成功');
	               }
	               // 没有成功的图片，重设
	               else {
	                  state = 'done';
//	                  location.reload();
	               }
	               break;
            }
            updateStatus();
        }
        
        uploader.onUploadProgress = function(file, percentage) {
            var $li;
            if(imageFlag){
            	$li = $('#'+id +file.id),
 	            $percent = $li.find('.progress span');
            	$percent.css( 'width', percentage * 100 + '%' );
        	      
            }else{
            	$li= $('#'+id + file.id).find(".prog_bar"),
	           $percent = $li.find('.progress span');
	           $percent.eq(0).text(Math.round(percentage * 100) + '%');
	           $percent.eq(1).css('width', Math.round(percentage * 100) + '%');
            }
            percentages[file.id][1] = percentage;
            updateTotalProgress();
        };

        uploader.onFileQueued = function(file) {
        	if (fileCount <= opts.maxUploadNum){
                addFile(file)
        	}else{
        		showMessage("您只能上传"+opts.maxUploadNum+"个文件");
        	}
        };

        uploader.onFileDequeued = function(file) {
        	fileCount--;
            if (!fileCount) {
                setState('pedding');
            }
            fileSize -= file.size;
            delete percentages[file.id];
            updateTotalProgress();
            if(imageFlag){
            	$('#'+id + file.id).off().find('.file-panel').off().end().remove();
            }else{
            	$('#'+id + file.id).remove();
            }
        };

        uploader.on('all',function(type, aa) {
            var stats;
            switch (type) {
                case 'uploadFinished':
	               setState('confirm');
	               break;
                case 'startUpload':
	               setState('uploading');
	               break;
                case 'stopUpload':
	               setState('paused');
	               break;
            }
        });

        uploader.onError = function(code){
            var text = "";
            switch (code) {
                case 'Q_TYPE_DENIED':
	               text = "文件类型不对";
	               break;
                case 'F_EXCEED_SIZE':
	               text = "文件大小超出";
	               break;
                case 'F_DUPLICATE':
	               text = "不要选择重复文件";
	               break;
                case 'Q_EXCEED_NUM_LIMIT':
	               text = "您只能上传"+opts.maxUploadNum+"个文件";
	               break;
                case 'Q_EXCEED_SIZE_LIMIT':
	               text = "文件总大小超出";
	               break;
                default:
	               text = "上传错误，请重试";
	               break;
            }
            showMessage(text);
        };

    	uploader.on('uploadBeforeSend',  function(file, data, header) {
    		header['X_Requested_With'] = 'XMLHttpRequest';
    		data["fileMd5"] = $('#'+id + data.id + '_md5').val();
    	});
    	
    	uploader.on('uploadAccept', function(obj, ret, reject) {
    		var responseText = (ret._raw || ret);
    		var json = JSON.parse(responseText);
    		if (json.result == "false") {
    			reject(json.code);
    			//  return false;
    		}
    		var $li = $('#' + id + obj.file.id);
    		try {
    			var responseText = (ret._raw || ret),
    			json = JSON.parse(responseText);
    			if (imageFlag){
    				if (json.result == "true") {
        				$('<p class="error" title="'+ json.message+ '">'+ json.message+ '</p>').appendTo($li);
        			}else{
        				$('<p class="error" title="'+ json.message+ '">'+ json.message+ '</p>').appendTo($li);
        			}
    			}else{
    				if (json.result == "true") {
        				$li.find('.msg').html('<span class="label label-sm label-success" title="'+ json.message+ '">'+ json.message+ '</span>');
        			}else{
        				$li.find('.msg').html('<span class="label label-sm label-danger" title="'+ json.message+ '">'+ json.message+ '</span>');
        			}
    			}
    		} catch(e) {
    			if (imageFlag){
    				$('<p class="error">服务器返回出错</p>').appendTo($li);
    			}else{
        			$li.find('.msg').html('<span class="label label-sm label-danger">服务器返回出错</span>');
    			}
    		}
    	});
    	
    	uploader.on('uploadSuccess',  function(file, ret) {
    		var $btncancel = $('#' + id + file.id).find('.btncancel');
    		var $filePanel = $('#' + id + file.id).find('.file-panel');
    		var $prgress = $('#' + id + file.id).find('.progress span');
    		try {
    			var responseText = (ret._raw || ret),
    			json = JSON.parse(responseText);
    			if (json.result == "true") {
    				var fileDownloadPath = (json.fileDownloadPath.startWith(opts.ctxPath) ? '' : opts.ctxPath) + json.fileDownloadPath;
    				if (imageFlag){
    					$filePanel.find('.cancel').attr('fileId', json.fileId).attr('fileUserId', json.fileUserId)
    						.attr('fileDownloadPath', fileDownloadPath).attr('fileName', json.fileName);
    				}else{
        				$btncancel.find('a').hide();
        				$('<a class="btn default btn-xs red" fileId="' + json.fileId + '" fileUserId="' + json.fileUserId 
    						+ '" fileDownloadPath="' + fileDownloadPath + '" fileName="' + json.fileName + '"><i class="fa fa-trash-o"></i> 删除 </a>'
    						+ '<a class="btn default btn-xs blue" target="_blank" href="'+opts.ctx+'/file/download/' + json.fileUserId + '.html" >'
    						+ '<i class="fa fa-download"></i> 下载 </a>').appendTo($btncancel);
    				}
					if (opts.returnPath){
						filePaths.push(fileDownloadPath);
						fileNames.push(json.fileName);
	    				$('#'+id).val(filePaths.join('|'));
	    				$('#'+opts.filePathInputId).val($('#'+id).val());
						$('#'+opts.fileNameInputId).val(fileNames.join('|'));
					}else{
						fileUsers.push(json.fileUserId);
	    				$('#'+id).val(fileUsers.join(','));
					}
    			} else {
    				$prgress.eq(0).text('0%');
    				$prgress.eq(1).css('width', '0%');
    			}
    		} catch(e) {
    			$prgress.eq(0).text('0%');
    			$prgress.eq(1).css('width', '0%');
    		}
    	});
    	
        $upload.on('click',  function() {
            if ($(this).hasClass('disabled')) {
                return false;
            }
            if (state === 'ready') {
                uploader.upload();
            } else if (state === 'paused') {
                uploader.upload();
            } else if (state === 'uploading') {
                uploader.stop();
            }
        });

        $info.on('click', '.retry', function() {
            uploader.retry();
            return false;
        });

        $info.on('click', '.ignore', function() {
            var file,i, files = uploader.getFiles('error');
            for (i = 0; file = files[i++];) {
                uploader.removeFile(file);
            }
            setState('finish');
            updateTotalProgress();
            return false;
        });

        $upload.addClass('state-' + state);
        updateTotalProgress();

    	// 初始化文件列表
		$this.refreshFileList = function(data){
			$queue.empty(); fileCount = 0; fileSize = 0;
			fileUsers = []; filePaths = []; fileNames = [];
			if(imageFlag){
				if(data && data.length > 0){
					for(var i = 0; i < data.length; i++){
						var t = data[i], fileDownloadPath = (t.fileUser.fileEntity.fileDownloadPath.startWith(opts.ctxPath) ? '' : opts.ctxPath) + t.fileUser.fileEntity.fileDownloadPath,
						$li = $('<li id="'+ t.fileUserBizId + '">'
							+ '<p class="title"><a target="_blank" href="' + (t.fileUser.fileUserId == '' ? fileDownloadPath : opts.ctx + '/file/download/' + t.fileUser.fileUserId + '.html') + '">' + (t.fileUser.fileUserId == '' ? '' : t.fileUser.fileName) + '</a></p>'
							+ '<p class="imgWrap"><img src="' + fileDownloadPath + '"></p>'
	           				+ '<p class="progress"><span></span></p>'
	           				+ '</li>'),
            			$btns = $('<div class="file-panel">'
            				+ '<span class="cancel ' + (!opts.readonly ? '' : 'hide' ) + '" fileUserId="' + t.fileUser.id + '" fileUserBizId="' + t.fileUserBizId
            				+ '" fileId="' + t.fileUser.fileEntity.fileId + '" fileSize="' + t.fileUser.fileEntity.fileSize
            				+ '" fileDownloadPath="' + fileDownloadPath + '" fileName="' + t.fileUser.fileName + '">删除</span>'
            				//+ '<span class="rotateRight">向右旋转</span>'
            				//+ '<span class="rotateLeft">向左旋转</span>'
            				+ '</div>').appendTo($li);
						
						$li.on('mouseenter', function() {
	            			var index = $(this).index();
							$queue.find('.file-panel').eq(index).stop().animate({height: 30});
//	            			$btns.stop().animate({height: 30});
	            		});

	            		$li.on('mouseleave', function() {
	            			var index = $(this).index();
							$queue.find('.file-panel').eq(index).stop().animate({height: 0});
//	            			$btns.stop().animate({height: 0});
	            		});

	            		$btns.on('click', 'span', function() {
	            			var index = $(this).index(),
	                        	$li = $(this).parents('li'),
	            				fileRotation = $(this).parent().data('fileRotation');
        					if (!fileRotation){
        						fileRotation = 0;
        					}
	            			switch ( index ) {
	            				case 0:
	            					if(!eval(opts.readonly)){
	     		                        var fuid = $(this).attr("fileUserId"),
	     		                    		fileId = $(this).attr("fileId"),
	     		                    		fileSize = $(this).attr("fileSize"),
	     		                        	fileDownloadPath = $(this).attr("fileDownloadPath"),
	     		                        	fileName = $(this).attr("fileName"),
	     		                        	formData = {"fileUserId" : fuid, "fileUserBizId" : $(this).attr("fileUserBizId")};
	     		                        if (opts.returnPath){
	     		                        	confirmx("确定删除该图片吗？  ", function(data) {
												filePaths.splice($.inArray(fileDownloadPath, filePaths), 1);
												fileNames.splice($.inArray(fileName, fileNames), 1);
												$('#'+id).val(filePaths.join('|'));
												$('#'+opts.filePathInputId).val($('#'+id).val());
												$('#'+opts.fileNameInputId).val(fileNames.join('|'));
												uploader.onFileDequeued({id: 0, size: 0});
												$li.remove();
	     		                        	});
	    		                        }else{
	    		                        	confirmx("确定删除该图片吗？  确定后即生效！", opts.ctx+"/file/delFileBiz", formData,  function(data) {
	         		                           if (data) {
	         		                               if (data.result == "true") {
         	 		                            		fileUsers.splice($.inArray(fuid, fileUsers), 1);
              		                            	    $('#'+id).val(fileUsers.join(','));
	         		                            		uploader.onFileDequeued({id: fileId, size: fileSize});
	         		                                    $('#'+formData["fileUserBizId"]).remove();
	         		                               }
	         		                               showMessage(data.message);
	         		                           }
	         		                       });
	    		                        }
	        						}
	            					return;
	            				case 1:
	            					fileRotation += 90;
	            					break;
	            				case 2:
	            					fileRotation -= 90;
	            					break;
	            			}
	            			var $liIndex = $(this).parent().parent().index();
	            			var imgWrap = $queue.find('.imgWrap :eq('+$liIndex+')');
	            			if (supportTransition) {
	            				var deg = 'rotate(' + fileRotation + 'deg)';
	            				imgWrap.css({
	            					'-webkit-transform': deg,
	            					'-mos-transform': deg,
	            					'-o-transform': deg,
	            					'transform': deg
	            				});
	            			} else {
	            				imgWrap.css('filter', 'progid:DXImageTransform.Microsoft.BasicImage(rotation='+ (~~((fileRotation/90)%4 + 4)%4) +')');
	            			}
        					$(this).parent().data('fileRotation', fileRotation);

	            		});
						fileCount++;
						fileSize += t.fileUser.fileEntity.fileSize;
						$queue.append($li);
                      	if (opts.returnPath){
                     		filePaths.push(fileDownloadPath);
                     		fileNames.push(t.fileUser.fileName);
    	    				$('#'+id).val(filePaths.join('|'));
    	    				$('#'+opts.filePathInputId).val($('#'+id).val());
    	    				$('#'+opts.fileNameInputId).val(fileNames.join('|'));
                     	}else{
                     		fileUsers.push(t.fileUser.id);
    	    				$('#'+id).val(fileUsers.join(','));
                     	}
					}
				}
			}else{
				if(data && data.length > 0){
					for(var i = 0; i < data.length; i++){
						var t = data[i], fileDownloadPath = (t.fileUser.fileEntity.fileDownloadPath.startWith(opts.ctxPath) ? '' : opts.ctxPath) + t.fileUser.fileEntity.fileDownloadPath,
						$li = $('<tr id="' + t.fileUserBizId + '"  class="template-upload ">'
							+ '<td class="name">' + t.fileUser.fileName + '</td>'
							+ '<td class="size">' + (t.fileUser.fileEntity.fileSize == 0 ? '' : WebUploader.formatSize(t.fileUser.fileEntity.fileSize)) + '</td>'
							+ '<td class="prog_bar"></td><td class="msg"></td>'
							+ '</tr>'),
						$btns = $('<td class="btncancel">'
							+ '<a class="btn default del btn-xs red ' + (!opts.readonly ? '' : 'hide' ) + '" fileUserId="' + t.fileUser.id + '" fileUserBizId="' + t.fileUserBizId 
            				+ '" fileId="' + t.fileUser.fileEntity.fileId + '" fileSize="' + t.fileUser.fileEntity.fileSize
							+ '" fileDownloadPath="' + fileDownloadPath + '" fileName="' + t.fileUser.fileName + '"><i class="fa fa-trash-o"></i> 删除 </a>'
							+ '<a class="btn default btn-xs blue" target="_blank" href="' + (t.fileUser.fileUserId == '' ? fileDownloadPath : opts.ctx + '/file/download/' + t.fileUser.fileUserId + '.html') + '"><i class="fa fa-download"></i> 下载 </a>'
							+ '</td>').appendTo($li);
						if(!opts.readonly){
							$btns.on('click', 'a.del', function() {
		                        var fuid = $(this).attr("fileUserId"),
		                    		fileId = $(this).attr("fileId"),
 		                    		fileSize = $(this).attr("fileSize"),
		                        	fileDownloadPath = $(this).attr("fileDownloadPath"),
		                        	fileName = $(this).attr("fileName"),
		                        	formData = {"fileUserId": fuid, "fileUserBizId": $(this).attr("fileUserBizId")};
		                        if (opts.returnPath){
 		                        	confirmx("确定删除该文件吗？  ", function(data) {
 		                        		filePaths.splice($.inArray(fileDownloadPath, filePaths), 1);
 		                        		fileNames.splice($.inArray(fileName, fileNames), 1);
	                            	    $('#'+id).val(filePaths.join('|'));
	                            	    $('#'+opts.filePathInputId).val($('#'+id).val());
	            	    				$('#'+opts.fileNameInputId).val(fileNames.join('|'));
	                            		uploader.onFileDequeued({id: 0, size: 0});
	                            	    $li.remove();
 		                        	});
		                        }else{
		                        	confirmx("确定删除该文件吗？  确定后即生效！", opts.ctx+"/file/delFileBiz", formData,  function(data) {
     		                           if (data) {
     		                               if (data.result == "true") {
 	 		                            		fileUsers.splice($.inArray(fuid, fileUsers), 1);
      		                            	    $('#'+id).val(fileUsers.join(','));
     		                            		uploader.onFileDequeued({id: fileId, size: fileSize});
     		                                    $('#'+formData["fileUserBizId"]).remove();
     		                               }
     		                               showMessage(data.message);
     		                           }
     		                       });
		                        }
		                        return;
			               });
						}
						fileCount++;
						fileSize += t.fileUser.fileEntity.fileSize;
						$queue.append($li);
                     	if (opts.returnPath){
                     		filePaths.push(fileDownloadPath);
                     		fileNames.push(t.fileUser.fileName);
    	    				$('#'+id).val(filePaths.join('|'));
    	    				$('#'+opts.filePathInputId).val($('#'+id).val());
    	    				$('#'+opts.fileNameInputId).val(fileNames.join('|'));
                     	}else{
                     		fileUsers.push(t.fileUser.id);
    	    				$('#'+id).val(fileUsers.join(','));
                     	}
					}
				} 					
			}
			if (fileUsers.length > 0 || filePaths.length > 0){
				if(!eval(opts.readonly)){
					$statusBar.show();
				}
				setState('ready');
	            updateTotalProgress();
			}
		}
		
		// 初始化文件路径中的文件列表
		$this.refreshFileListByPath = function(){
			var data = [], paths = [], names,
				fp = $('#'+opts.filePathInputId).val(),
				fn = $('#'+opts.fileNameInputId).val(),
				vs = $('#'+id).val();
				
			// 获取路径列表
			if (fp != undefined && fp != ''){
				paths = fp.split('|');
			}else if (vs != undefined && vs != ''){
				paths = vs.split('|');
			}
			
			// 获取名称列表
			if (fn != undefined && fn != ''){
				names = fn.split('|');
			}
			
			// 如果两个长度不相等，则将路径设置到名称
			if (names == undefined || names.length != paths.length){
				names = paths;
			}
			
			// 输出文件列表
			$.each(paths, function(i, v){
				data.push({
					fileUser: {
						fileEntity: {
							fileDownloadPath: v,
							fileId: "",
							filePath: "",
							fileSize: 0,
							fileSuffix: "",
							id: ""
						},
						fileName: names[i].split("/")[names[i].split("/").length-1],
						fileUserId: "",
						id: ""
					},
					fileUserBizId: "",
					id: ""
				});
			});
			$this.refreshFileList(data);
		}
		
		// 初始化业务关系数据文件列表
		$this.refreshFileListByBizData = function(){
			$.ajax({
				url : opts.ctx+"/file/fileList?___t=" + new Date().getTime(),
				data : {
		   			"bizCategory" : opts.bizCategory,
		   			"bizKey" : opts.bizKey
			   	},
				dataType : 'json',
				success : function(data){
					if (!(data.result == "false")) {
						$this.refreshFileList(data);
					}
				}
			});
    	}
		
		// 执行初始化方法
		if (opts.returnPath){
			$this.refreshFileListByPath();
		}else{
			$this.refreshFileListByBizData();
		}
		
    	return $this;
    	
	}

	$.fn.webuploader = function (option, value) {
		var method_call;
		
		var $set = this.each(function () {
			var $this = $(this);
			var data = $this.data('webuploader');
			var options = typeof option === 'object' && option;

			if (!data) $this.data('webuploader', (data = new Webuploader(options, $this)));
			if (typeof option === 'string' && typeof data[option] === 'function') {
				if(value instanceof Array) method_call = data[option].apply(data, value);
				else method_call = data[option](value);
			}
		});

		return (method_call === undefined) ? $set : method_call;
	};
	
	$.fn.webuploader.defaults = {
		id : '', 				// 唯一标识id
		bizCategory : '', 		// name, 业务表分类（一种业务下不能重复）
		bizKey : '', 			// value, 业务表的主键值（与附件关联的业务数据）
	    returnPath : false, 	// 是否是返回文件路径到输入框（默认false）
	    filePathInputId: '', 	// 设置文件路径存放的输入框的ID，当returnPath为true的时候，返回文件路径到这个输入框
	    fileNameInputId: '', 	// 设置文件名称存放的输入框的ID，当returnPath为true的时候，返回文件名称到这个输入框
		uploadType : '', 		// 上传文件类型 all、file、image、media
		readonly : false, 		// 只读模式为，查看模式
		imageMaxWidth : 1024, 	// 最大宽度(uploadType为image生效)
		imageMaxHeight :768, 	// 最大高度(uploadType为image生效)
		allowServerSelect : false, 		// 是否允许从服务器上选
		maxUploadNum : 300, 			// 多文件下允许最多上传几个 -1为不限制
		lazyUpload : false, 			// 设置为ture需要点击上传按钮才上传文件，否则选择后就直接上传
	    maxFileSize : 5*1024*1024, 		// 单个文件，最大上传文件大小限制（5M）
	    maxFilesSize : 100*1024*1024, 	// 全部文件，最大上传文件大小限制（100M）
		ctxPath : '', 	// contextPath
		ctx : '', 		// contextPath + adminPath
		ctxStatic : '' 	// contextPath + static
	};
	
})(jQuery);